package com.alibaba.cloud.ai.example.helloworld.controller;

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.alibaba.cloud.ai.example.flight.service.FlightService;
import com.alibaba.cloud.ai.example.helloworld.advisor.LoggingAdvisor;
import com.alibaba.cloud.ai.example.helloworld.tools.FlightCallTool;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

/**
 * 航空的
 */

@CrossOrigin
@RestController
@RequestMapping("/flight/ai")
public class Test05FlightController {


    @Autowired
    private FlightService flightService;

    private final ChatClient dashScopeChatClient;

    // 也可以使用如下的方式注入 ChatClient
    public Test05FlightController(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory) {
        this.dashScopeChatClient = chatClientBuilder.defaultSystem("""
                        您是ALI航空公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来
                         您正在通过在线聊天系统与客户互动。
                         在提供有关预订或取消预订的信息之前，您必须始终从用户处获取以下信息：预订号、客户姓名。
                         在询问用户之前，请检查消息历史记录以获取此信息。
                         请讲中文。
                         今天的日期是 {current_date}
                        """)

                // 实现 Chat Memory 的 Advisor
                // 在使用 Chat Memory 时，需要指定对话 ID，以便 Spring AI 处理上下文。
                .defaultAdvisors(new PromptChatMemoryAdvisor(chatMemory), new LoggingAdvisor())
                // 实现 Logger 的 Advisor
                .defaultAdvisors(new SimpleLoggerAdvisor())
                // 设置 ChatClient 中 ChatModel 的 Options 参数
                .defaultOptions(DashScopeChatOptions.builder().withTopP(0.7).build()).build();
    }

    /**
     * ChatClient 简单调用-设置advisors拦截器
     */
    @GetMapping("/tool/chat/{sessionId}")
    public String advisorChat(HttpServletResponse response, @PathVariable String sessionId, @RequestParam String query) {
        response.setCharacterEncoding("UTF-8");

        return this.dashScopeChatClient.prompt(query)
                .system(systemSpec -> systemSpec.param("current_date", LocalDate.now().toString()))
                .advisors(systemSpec -> systemSpec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, sessionId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
                .tools(new FlightCallTool(flightService)).call().content();
    }
}
